#include "tthread.h"

namespace tlib
{
TThread::TThread() :
	m_bDetached(false), m_bActivated(false)
{

}

TThread::~TThread()
{
	Cannel();
}
#ifdef WIN32
void TThread::GlobleThread(void* param)
{
	((TThread*)(param))->m_task();
}
#else
void* TThread::GlobleThread(void* param)
{
	((TThread*) (param))->m_task();
}
#endif

bool TThread::Run(TTask task)
{
	if (m_bActivated)
		return false;
	m_task = task;
#ifdef WIN32
	if ((m_th = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&TThread::GlobleThread, this, 0, &m_thid)) == NULL)
	return false;
#else
	if (pthread_create(&m_th, &m_attr, &GlobleThread, this) != 0)
		return false;
#endif
	m_bActivated = true;
	return true;
}

bool TThread::Cannel()
{
#ifdef WIN32
	if (m_bActivated)
	if (!CloseHandle(m_th))
	return false;
#else
	if (m_bActivated)
		if (pthread_cancel(m_th) != 0)
			return false;
#endif
	m_bActivated = false;
	return true;
}

bool TThread::Join()
{
	if (m_bDetached || !m_bActivated)
		return false;
#ifdef WIN32
	if (!WaitForSingleObject(m_th, INFINITE))
	return false;
#else
	if (pthread_join(m_th, NULL) != 0)
		return false;
#endif
	m_bActivated = false;
	return true;
}

bool TThread::SetDetach()
{
#ifdef WIN32
	return false;
#else
	if (pthread_attr_setdetachstate(&m_attr, PTHREAD_CREATE_DETACHED) != 0)
		return false;
	m_bDetached = true;
	return true;
#endif
}

bool TThread::UnsetDetach()
{
#ifdef WIN32
	return false;
#else
	if (pthread_attr_setdetachstate(&m_attr, PTHREAD_CREATE_JOINABLE) != 0)
		return false;
	m_bDetached = false;
	return true;
#endif
}

bool TThread::GetDetach()
{
#ifdef WIN32
	return false;
#else
	return m_bDetached;
#endif
}

bool TThread::IsActivated()
{
	return m_bActivated;
}
}
